/*
这是一个只会进攻的AI的样例
*/

#include "sdk/sdk.h"
#include "sdk/misc.h"
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <cstdio>
#include <cassert>

using Pos = SDK::Pos;
using PPlayerInfo = SDK::PPlayerInfo;
using PCommand = SDK::PCommand;
using PShowInfo = SDK::PShowInfo;
using Edge = PPlayerInfo::Edge;
using Robot = PPlayerInfo::Robot;
using HumanOrder = PPlayerInfo::HumanOrder;
using Buff = Robot::Buff;
using Skill = Robot::Skill;
using Operation = PCommand::Operation;
using ShowInfo = PShowInfo::ShowInfo;

PPlayerInfo playerInfo;
PCommand pCommand;

//样例AI
class AttackAI1
{
private:
	//对局开始的初始化
	void init()
	{
		//srand(time(0));
	}

public:

	//主过程，通过playerInfo得到pCommand
	void solve()
	{
        pCommand.cmds.clear();
		if (playerInfo.round == 0)
			init();

		vector<Robot*>MyRobot, EnemyRobot;//我方机器人列表，敌方机器人列表
		vector<Pos>BuildAblePos;//当前地图上的空地
		//构造MyRobot, EnemyRobot
		for (unsigned int i = 0; i < playerInfo.robots.size(); i++)
		{
			Robot& obj = playerInfo.robots[i];
			if (obj.team == playerInfo.team)
				MyRobot.push_back(&obj);
			else
				EnemyRobot.push_back(&obj);
		}

		for (int x = 0; x < MAP_SIZE; x++)
			for (int y = 0; y < MAP_SIZE; y++)
				if (MAP[x][y] == 1 && playerInfo.RobotAt(Pos(x, y)) == NULL)
					BuildAblePos.push_back(Pos(x, y));
		//将数组随机打乱
		random_shuffle(MyRobot.begin(), MyRobot.end());
		random_shuffle(EnemyRobot.begin(), EnemyRobot.end());
		random_shuffle(BuildAblePos.begin(), BuildAblePos.end());
		for(auto my: MyRobot)
		{
			for(auto ene: EnemyRobot)
			{
				int dx = my->pos.x - ene->pos.x;
				int dy = my->pos.y - ene->pos.y;
				if(dx * dx + dy * dy <= my->attack_range)
				{
					pCommand.AddOrder(PlainAttack, my->pos, ene->pos);
					break;
				}
			}
			if(my->energy >= my->consumption + Robot::Skill::Cost(SplitSkill, my->level, my->type) && BuildAblePos.size())
			{
				for (int i = 0; i < BuildAblePos.size(); ++ i){
					int dx = my->pos.x - BuildAblePos[i].x;
					int dy = my->pos.y - BuildAblePos[i].y;
					if (dx * dx + dy * dy <= SplitRange){
						pCommand.AddOrder(Split, my->pos, BuildAblePos[i]);
						BuildAblePos.erase(BuildAblePos.begin() + i);
						break;
					}
				}

			}
			fflush(stdout);
		}
	}

}attackAI1;


//普通AI接口，一回合调用一次
extern "C"
{
__declspec(dllexport) void player_ai(const PlayerInfo &playerInfo_, Commands &pCommand_, PShowInfo &pShowInfo_) {
	playerInfo = SDK::interpretPlayerInfo(playerInfo_);
    attackAI1.solve();
    pCommand_ = SDK::translateCommands(playerInfo, pCommand);
    return;
}
}
